package com.danicsoft.daide.command;

import java.util.List;

import com.danicsoft.daide.token.TokenGroup;
import com.danicsoft.daide.token.TokenMap;

/**
 * Implements the NOW command. From Eric Wald's <a
 * href="http://pydip.brainshell.org/docs/syntax.html">protocol specification</a>,
 * v0.14:
 * <h4><a name="NOW">server_message = NOW</a> (turn) (unit) (unit) ...</h4>
 * <p>
 * This is sent from the server to the client at the start of the game, and
 * after every turn. It indicates the current turn, and the current unit
 * positions. For example, at the start of the game:
 * </p>
 * <p>
 * <b>NOW (SPR 1901) (AUS FLT TRI) (AUS AMY BUD) (AUS AMY VIE) (ENG FLT LON) ...</b>
 * </p>
 * <p>
 * Fleets in multi-coastal provinces have a province and coast bracketed
 * together. For example:
 * </p>
 * <p>
 * <b>(RUS FLT (STP SCS))</b>
 * </p>
 * <p>
 * Before a retreat turn, units may have a list of retreat options, prefixed by
 * <b>MRT</b> (Must retreat to). For example:
 * </p>
 * <p>
 * <b>(ENG FLT NTH MRT (LON YOR EDI NWG))</b>
 * </p>
 * <p>
 * If a unit has no possible retreats, then it will still be listed, and the
 * player still must order the disband. For example:
 * </p>
 * <p>
 * <b>(ENG FLT NTH MRT ())</b>
 * </p>
 * <p>
 * Retreat options will include a coast if a fleet can retreat to a
 * multi-coastal province. For example,
 * </p>
 * <p>
 * <b>(TUR FLT CON MRT (BLA SMY (BUL ECS) (BUL SCS)))</b>
 * </p>
 * <p>
 * The client can send the command <b>NOW</b> to the server with no arguments
 * at any time. The server will reply by sending another copy of the latest
 * <b>NOW</b> message, or <b>REJ (NOW)</b> if the game hasn't started.
 * </p>
 * 
 * @author Daniel Yule (daniel.yule@gmail.com)
 * @version 1.0
 */
public class NowCommand extends QueryableCommand {

	/**
	 * The turn this command is for.
	 */
	private Turn thisTurn;

	/**
	 * The unit positions on the map this turn.
	 */
	private List<UnitPos> unitPositions;

	@Override
	public void initialize() {
		super.initialize();
		thisTurn = new Turn();
	}

	/**
	 * Construct a <code>NowCommand</code> from the <code>TokenGroup</code>
	 * specified.
	 * 
	 * @param tokens
	 *        A <code>TokenGroup</code> that contains the information for this
	 *        command
	 * @throws ParseException
	 */
	public NowCommand(TokenGroup tokens) throws ParseException {
		super(tokens);
	}

	/**
	 * Construct a <code>NowCommand</code> for sending to the server as a
	 * query to recieve a <code>NowCommand</code> back for the current turn.
	 */
	public NowCommand() {
		super();
	}

	/**
	 * Construct a new NowCommand for the given turn and the given unit
	 * positions
	 * 
	 * @param turn
	 *        The turn this is a command for.
	 * @param positions
	 *        The positions of units.
	 */
	public NowCommand(Turn turn, List<UnitPos> positions) {
		super(false);
		thisTurn = turn;
		unitPositions = positions;
	}

	@Override
	protected void doNonQueryIO(TokenIO tokenIO, TokenGroup tokens) throws ParseException {
		thisTurn.doIO(tokenIO, tokens);
		unitPositions = tokenIO.doList(tokens, unitPositions, new RetreatableUnitPos());

	}

	@Override
	public byte getType() {
		return TokenMap.Commands.NOW;
	}

	@Override
	public String toString() {
		return "Positions command for " + thisTurn;
	}

	/**
	 * Gets the unit positions for this turn.
	 * 
	 * @return The unit positions.
	 */
	public Iterable<UnitPos> positions() {
		return unitPositions;
	}

	/**
	 * Get the turn that this command is for.
	 * 
	 * @return The turn for this command.
	 */
	public Turn getTurn() {
		return thisTurn;
	}

	/**
	 * Sets the turn for this NowCommand.
	 * 
	 * @param curTurn
	 */
	public void setTurn(Turn curTurn) {
		thisTurn = curTurn.clone();

	}

}
